package api

import (
	"NanmuHubNIC510/hub"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"paco_toolkit/NIC510"
	"paco_toolkit/common"
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/text/gstr"
	"github.com/gogf/gf/util/grand"
)

func GetClock(r *ghttp.Request) {
	res := g.Map{
		"code": 0,
		"msg":  "",
		"data": nil,
	}
	addr := r.GetString("addr")
	c := hub.CreateMqttClient("cid_Hub_"+grand.Digits(10), nil, nil)
	if token := c.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	topic_s := "S/NIC510/" + addr
	topic_p := "P/NIC510/" + addr

	var data []byte
	size := 0
	msg := NIC510.CreateMsg(0x03, 0, uint16(size), data)
	g.Log().Line(true).Debugf("send msg: % X", msg)
	// 订阅主题
	var iscallback bool
	var pack *NIC510.Pack
	var err error

	if token := c.Subscribe(topic_p, 0, func(c mqtt.Client, msg mqtt.Message) {
		topic := msg.Topic()
		topic_arr := gstr.Split(topic, "/")
		addr := topic_arr[2]
		g.Log().Line(true).Debug("NIC510 recv from topic:" + msg.Topic())
		g.Log().Line(true).Debug("NIC510 recv from addr:" + addr)
		g.Log().Line(true).Debugf("NIC510 recv msg: % X", msg.Payload())

		//解析返回
		pack, err = NIC510.DecodePack(msg.Payload())
		if err == nil {
			if pack.C == 0x83 {
				iscallback = true

			}
		} else {
			iscallback = true
		}

	}); token.Wait() && token.Error() != nil {
		g.Log().Line(true).Error(token.Error())
	}

	// 发布消息
	token := c.Publish(topic_s, 0, false, msg)
	token.Wait()

	for i := 0; i <= 100; i++ {
		if iscallback {
			//解析返回
			if err != nil {
				res["code"] = -1
				res["msg"] = err.Error()
			} else {
				res["code"] = 0
				res["data"] = fmt.Sprintf("20%02X-%02X-%02X %02X:%02X:%02X", pack.Data[0], pack.Data[1], pack.Data[2], pack.Data[3], pack.Data[4], pack.Data[5])
			}
			break
		} else {
			//继续等待
			time.Sleep(100 * time.Millisecond)
		}
	}
	c.Disconnect(250)
	if !iscallback {
		res["code"] = -1
		res["msg"] = "超时"
	}
	r.Response.WriteJson(res)
	r.ExitAll()
}

func SetClock(r *ghttp.Request) {
	res := g.Map{
		"code": 0,
		"msg":  "",
		"data": nil,
	}
	addr := r.GetString("addr")
	c := hub.CreateMqttClient("cid_Hub_"+grand.Digits(10), nil, nil)
	if token := c.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	topic_s := "S/NIC510/" + addr
	topic_p := "P/NIC510/" + addr

	//校时日期
	var datetime = gtime.Now().Format("ymdHis")
	clock, _ := hex.DecodeString(datetime)

	var data []byte
	data = append(data, clock...)

	msg := NIC510.CreateMsg(0x03, 1, uint16(len(data)), data)
	g.Log().Line(true).Debugf("send msg: % X", msg)
	// 订阅主题
	var iscallback bool
	var pack *NIC510.Pack
	var err error

	if token := c.Subscribe(topic_p, 0, func(c mqtt.Client, msg mqtt.Message) {
		topic := msg.Topic()
		topic_arr := gstr.Split(topic, "/")
		addr := topic_arr[2]
		g.Log().Line(true).Debug("NIC510 recv from topic:" + msg.Topic())
		g.Log().Line(true).Debug("NIC510 recv from addr:" + addr)
		g.Log().Line(true).Debugf("NIC510 recv msg: % X", msg.Payload())

		//解析返回
		pack, err = NIC510.DecodePack(msg.Payload())
		if err == nil {
			if pack.C == 0x83 {
				iscallback = true

			}
		} else {
			iscallback = true
		}

	}); token.Wait() && token.Error() != nil {
		g.Log().Line(true).Error(token.Error())
	}

	// 发布消息
	token := c.Publish(topic_s, 0, false, msg)
	token.Wait()

	for i := 0; i <= 100; i++ {
		if iscallback {
			//解析返回
			if err != nil {
				res["code"] = -1
				res["msg"] = err.Error()
			} else {
				if pack.Data[0] == 0x00 {
					res["code"] = 0
					res["msg"] = "设置成功"
				} else {
					res["code"] = -1
					res["msg"] = "设置失败"
				}
			}
			break
		} else {
			//继续等待
			time.Sleep(100 * time.Millisecond)
		}
	}
	c.Disconnect(250)
	if !iscallback {
		res["code"] = -1
		res["msg"] = "超时"
	}
	r.Response.WriteJson(res)
	r.ExitAll()
}

func GetStatus(r *ghttp.Request) {

	res := g.Map{
		"code": 0,
		"msg":  "",
		"data": nil,
	}

	addr := r.GetString("addr")

	c := hub.CreateMqttClient("cid_Hub_"+grand.Digits(10), nil, nil)
	if token := c.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	topic_s := "S/NIC510/" + addr
	topic_p := "P/NIC510/" + addr
	var data []byte
	var status NIC510.State
	size := uint16(binary.Size(status))
	msg := NIC510.CreateMsg(02, 0, size, data)
	g.Log().Line(true).Debugf("send msg: % X", msg)

	// 订阅主题
	var iscallback bool
	var pack *NIC510.Pack
	var err error

	if token := c.Subscribe(topic_p, 0, func(c mqtt.Client, msg mqtt.Message) {
		topic := msg.Topic()
		topic_arr := gstr.Split(topic, "/")
		addr := topic_arr[2]
		g.Log().Line(true).Debug("NIC510 recv from topic:" + msg.Topic())
		g.Log().Line(true).Debug("NIC510 recv from addr:" + addr)
		g.Log().Line(true).Debugf("NIC510 recv msg: % X", msg.Payload())
		//解析返回
		pack, err = NIC510.DecodePack(msg.Payload())
		if err == nil {
			if pack.C == 0x82 {
				iscallback = true

			}
		} else {
			iscallback = true
		}

	}); token.Wait() && token.Error() != nil {
		g.Log().Line(true).Error(token.Error())
	}

	// 发布消息
	token := c.Publish(topic_s, 0, false, msg)
	token.Wait()

	for i := 0; i <= 100; i++ {
		if iscallback {
			//解析返回
			if err != nil {
				res["code"] = -1
				res["msg"] = err.Error()
			} else {
				f_status := NIC510.DecodeStatus(pack.Data)
				res["code"] = 0
				res["data"] = f_status
			}
			break
		} else {
			//继续等待
			time.Sleep(100 * time.Millisecond)
		}
	}
	c.Disconnect(250)
	if !iscallback {
		res["code"] = -1
		res["msg"] = "超时"
	}
	r.Response.WriteJson(res)
	r.ExitAll()
}

func GetParams(r *ghttp.Request) {
	res := g.Map{
		"code": 0,
		"msg":  "",
		"data": nil,
	}
	addr := r.GetString("addr")
	c := hub.CreateMqttClient("cid_Hub_"+grand.Digits(10), nil, nil)
	if token := c.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	topic_s := "S/NIC510/" + addr
	topic_p := "P/NIC510/" + addr
	var data []byte
	var param NIC510.Para
	size := uint16(binary.Size(param))
	msg := NIC510.CreateMsg(00, 0, size, data)
	g.Log().Line(true).Debugf("send msg: % X data size:%d", msg, size)

	// 订阅主题
	var iscallback bool
	var pack *NIC510.Pack
	var err error

	if token := c.Subscribe(topic_p, 0, func(c mqtt.Client, msg mqtt.Message) {
		topic := msg.Topic()
		topic_arr := gstr.Split(topic, "/")
		addr := topic_arr[2]
		g.Log().Line(true).Debug("NIC510 recv from topic:" + msg.Topic())
		g.Log().Line(true).Debug("NIC510 recv from addr:" + addr)
		g.Log().Line(true).Debugf("NIC510 recv msg: % X", msg.Payload())

		//解析返回
		pack, err = NIC510.DecodePack(msg.Payload())
		if err == nil {
			if pack.C == 0x80 {
				iscallback = true

			}
		} else {
			iscallback = true
		}

	}); token.Wait() && token.Error() != nil {
		g.Log().Line(true).Error(token.Error())
	}

	// 发布消息
	token := c.Publish(topic_s, 0, false, msg)
	token.Wait()

	for i := 0; i <= 50; i++ {
		if iscallback {
			//解析返回
			if err != nil {
				res["code"] = -1
				res["msg"] = err.Error()
			} else {
				fp, err := NIC510.DecodeParams(pack.Data)
				if err != nil {
					g.Log().Line(true).Error(err)
					res["code"] = -1
					res["msg"] = err.Error()
				} else {
					g.Log().Line(true).Infof("GetParams from %s:", addr)
					g.Log().Line(true).Info(fp)
					res["code"] = 0
					res["data"] = fp
				}

			}
			break
		} else {
			//继续等待
			time.Sleep(100 * time.Millisecond)
		}
	}
	c.Disconnect(250)
	if !iscallback {
		res["code"] = -1
		res["msg"] = "超时"
	}
	r.Response.WriteJson(res)
	r.ExitAll()
}

func SetParamsAll(r *ghttp.Request) {
	res := g.Map{
		"code": 0,
		"msg":  "",
		"data": nil,
	}
	addr := r.GetString("addr")

	params := r.GetString("params")
	c := hub.CreateMqttClient("cid_Hub_"+grand.Digits(10), nil, nil)
	if token := c.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	topic_s := "S/NIC510/" + addr
	topic_p := "P/NIC510/" + addr

	fp := NIC510.FPara{}
	//obj,_:=gjson.Decode(device.InterfaceParams) //转换成FParams对象格式
	gjson.DecodeTo(params, &fp)
	p := NIC510.EncodeParams(&fp)

	size := uint16(len(p))

	msg := NIC510.CreateMsg(01, 0, size, p[:size])
	g.Log().Line(true).Debugf("send msg: % X len=%d", msg, size)
	// 订阅主题
	var iscallback bool
	var pack *NIC510.Pack
	var err error

	if token := c.Subscribe(topic_p, 0, func(c mqtt.Client, msg mqtt.Message) {
		topic := msg.Topic()
		topic_arr := gstr.Split(topic, "/")
		addr := topic_arr[2]
		g.Log().Line(true).Debug("NIC510 recv from topic:" + msg.Topic())
		g.Log().Line(true).Debug("NIC510 recv from addr:" + addr)
		g.Log().Line(true).Debugf("NIC510 recv msg: % X", msg.Payload())

		//解析返回
		pack, err = NIC510.DecodePack(msg.Payload())
		if err == nil {
			if pack.C == 0x81 {
				iscallback = true

			}
		} else {
			iscallback = true
		}

	}); token.Wait() && token.Error() != nil {
		g.Log().Line(true).Error(token.Error())
	}

	// 发布消息
	token := c.Publish(topic_s, 0, false, msg)
	token.Wait()

	for i := 0; i <= 100; i++ {
		if iscallback {
			//解析返回
			if err != nil {
				res["code"] = -1
				res["msg"] = err.Error()
			} else {
				if pack.Data[0] == 0x00 {
					res["code"] = 0
					res["msg"] = "设置成功"
				} else {
					res["code"] = -1
					res["msg"] = "设置失败"
				}
			}
			break
		} else {
			//继续等待
			time.Sleep(100 * time.Millisecond)
		}
	}
	c.Disconnect(250)
	if !iscallback {
		res["code"] = -1
		res["msg"] = "10s timeout"
	}
	r.Response.WriteJson(res)
	r.ExitAll()
}

func SetParams(r *ghttp.Request) {
	res := g.Map{
		"code": 0,
		"msg":  "",
		"data": nil,
	}
	addr := r.GetString("addr")

	params := r.GetString("params")
	c := hub.CreateMqttClient("cid_Hub_"+grand.Digits(10), nil, nil)
	if token := c.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	topic_s := "S/NIC510/" + addr
	topic_p := "P/NIC510/" + addr

	g.Log().Line(true).Infof("SetParams addr:%s params : %s", addr, params)

	fp := NIC510.FPara{}
	//obj,_:=gjson.Decode(device.InterfaceParams) //转换成FParams对象格式
	gjson.DecodeTo(params, &fp)
	p := NIC510.EncodeParams(&fp)

	g.Log().Line(true).Info(fp)

	var res_err error
	for x := 0; x < 5; x++ {
		var _begin, _end, _len, prefix_len int64
		var _begin_offset, _end_offset int64
		prefix_len = 2
		if x == 0 {
			_begin = common.GetStructFieldOffset(NIC510.CzqPara{}, "Pid")
			_end = common.GetStructFieldOffset(NIC510.CzqPara{}, "Wind_fan")
			_begin_offset = _begin + prefix_len
			_end_offset = _end + prefix_len
		} else if x == 1 {
			_begin = common.GetStructFieldOffset(NIC510.CzqPara{}, "Wind_fan")
			_end = common.GetStructFieldOffset(NIC510.CzqPara{}, "Wind_vfanEx")
			_begin_offset = _begin + prefix_len
			_end_offset = _end + prefix_len

		} else if x == 2 {
			_begin = common.GetStructFieldOffset(NIC510.CzqPara{}, "Wind_vfanEx")
			_end = common.GetStructFieldOffset(NIC510.CzqPara{}, "RoomIdx")
			_begin_offset = _begin + prefix_len
			_end_offset = _end + prefix_len
		} else if x == 3 {
			_begin = common.GetStructFieldOffset(NIC510.CzqPara{}, "RoomIdx")
			var _czqpara = NIC510.CzqPara{}
			_end = int64(binary.Size(_czqpara))
			_begin_offset = _begin + prefix_len
			_end_offset = _end + prefix_len
		} else if x == 4 {
			_begin = int64(binary.Size(NIC510.CzqPara{}))
			_end = common.GetStructFieldOffset(NIC510.Para{}, "Rev")
			_begin_offset = _begin + prefix_len
			_end_offset = _end
		}
		_len = _end - _begin
		g.Log().Line(true).Debugf("part %d _begin=%d _end=%d", x, _begin, _end)
		g.Log().Line(true).Debugf("part %d _begin_offset=%d _end_offset=%d len=%d", x, _begin_offset, _end_offset, _len)
		size := uint16(_len)

		msg := NIC510.CreateMsg(01, uint16(_begin_offset), size, p[_begin_offset:_end_offset])
		g.Log().Line(true).Infof("send msg: % X len=%d", msg, size)
		// 订阅主题
		var iscallback bool
		var pack *NIC510.Pack
		var err error

		if token := c.Subscribe(topic_p, 0, func(c mqtt.Client, msg mqtt.Message) {
			topic := msg.Topic()
			topic_arr := gstr.Split(topic, "/")
			addr := topic_arr[2]
			g.Log().Line(true).Debug("NIC510 recv from topic:" + msg.Topic())
			g.Log().Line(true).Debug("NIC510 recv from addr:" + addr)
			g.Log().Line(true).Debugf("NIC510 recv msg: % X", msg.Payload())

			//解析返回
			pack, err = NIC510.DecodePack(msg.Payload())
			if err == nil {
				if pack.C == 0x81 {
					iscallback = true

				}
			} else {
				iscallback = true
			}

		}); token.Wait() && token.Error() != nil {
			g.Log().Line(true).Error(token.Error())
		}

		// 发布消息
		token := c.Publish(topic_s, 0, false, msg)
		token.Wait()

		for i := 0; i <= 50; i++ {
			if iscallback {
				//解析返回
				if err != nil {
					res_err = err
				} else {
					if pack.Data[0] == 0x00 {
					} else {
						res_err = errors.New(fmt.Sprintf("设置失败part=%d", x))
					}
				}
				break
			} else {
				//继续等待
				time.Sleep(100 * time.Millisecond)
			}
		}

		if !iscallback {
			res_err = errors.New(fmt.Sprintf("设置超时part=%d", x))
		}

		time.Sleep(500 * time.Millisecond)
		if res_err != nil {
			res["code"] = -1
			res["msg"] = res_err.Error()
			break
		}
	}

	if res_err == nil {
		res["code"] = 0
		res["msg"] = "设置成功"
	}
	c.Disconnect(250)
	r.Response.WriteJson(res)
	r.ExitAll()
}
